package com.gitee.wsl.mathematics.coordinate.polar.ext

import com.gitee.wsl.math.degreesToRadians
import com.gitee.wsl.math.radiansToDegrees
import com.gitee.wsl.mathematics.coordinate.polar.Polar
import com.gitee.wsl.mathematics.vector.vec2.Vec2
import com.gitee.wsl.mathematics.vector.vec2.Vec2f
import kotlin.math.atan2
import kotlin.math.cos
import kotlin.math.sin

/** Constructs equivalent Cartesian coordinates from the polar representation. */
val Polar.cartesian: Vec2
    get() {
        return Vec2.fromPolar(this)
    }

fun Vec2.Companion.fromPolar(polar: Polar): Vec2 {
    val theta = polar.theta.degreesToRadians()
    val x = cos(theta)
    val y = sin(theta)
    return Vec2(x, y) * polar.radius
}

/** Constructs equivalent polar coordinates from the Cartesian coordinate system. */
fun Polar(vector: Vec2): Polar {
    val r = vector.length
    return Polar(
        if (r == 0.0) 0.0 else atan2(vector.y, vector.x).radiansToDegrees(),
        r
    )
}

val Polar.cartesianF: Vec2f
    get() {
        return Vec2f.fromPolar(this)
    }

fun Vec2f.Companion.fromPolar(polar: Polar): Vec2f {
    val theta = polar.theta.degreesToRadians()
    val x = cos(theta)
    val y = sin(theta)
    return Vec2f(x, y) * polar.radius
}

/** Constructs equivalent polar coordinates from the Cartesian coordinate system. */
fun Polar(vector: Vec2f): Polar {
    val r = vector.length.toDouble()
    return Polar(
        if (r == 0.0) 0.0 else atan2(vector.y, vector.x).radiansToDegrees().toDouble(),
        r
    )
}